from datetime import datetime
from flask_login import UserMixin
from app.extensions import db

from app.utils.utils import canonical_slug


class BuyClick(db.Model):
    __tablename__ = 'buy_clicks'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('customer_users.id'), nullable=True)
    product_id = db.Column(db.Integer, db.ForeignKey('products.id'), nullable=False)
    channel = db.Column(db.String(20), nullable=False)  # 'direct' | 'email' | 'whatsapp' | 'wechat'
    created_at = db.Column(db.DateTime, default=datetime.utcnow, index=True)

    __table_args__ = (
        db.Index('idx_buyclicks_prod_time', 'product_id', 'created_at'),
    )


class Order(db.Model):
    __tablename__ = 'orders'
    id = db.Column(db.Integer, primary_key=True)
    # 归属用户
    user_id = db.Column(db.Integer, db.ForeignKey('customer_users.id'), index=True, nullable=False)
    product_id = db.Column(db.Integer)
    remark = db.Column(db.Text)
    # 业务编号（支付成功/对账后生成）
    order_no = db.Column(db.String(32), unique=True, index=True)
    # 金额
    amount = db.Column(db.Integer, nullable=False)  # 以“分”为单位存储
    currency = db.Column(db.String(8), default='USD', nullable=False)
    # 订单状态 / 履约状态
    status = db.Column(db.String(20), default='pending', nullable=False)  # pending/paid/cancelled
    fulfillment_status = db.Column(db.String(20), default='to_ship', nullable=False)  # to_ship/shipped
    # PayPal 关联
    paypal_order_id = db.Column(db.String(64))
    paypal_capture_id = db.Column(db.String(64))
    # 收件信息（确定订单页面必须填写）
    recipient_name = db.Column(db.String(120), nullable=False)
    recipient_email = db.Column(db.String(120), nullable=False)
    recipient_phone = db.Column(db.String(40), nullable=False)
    recipient_address = db.Column(db.String(255), nullable=False)
    recipient_postal_code = db.Column(db.String(20), nullable=False)
    # 时间
    created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
    paid_at = db.Column(db.DateTime)
    shipped_at = db.Column(db.DateTime)
    # 关系
    items = db.relationship('OrderItem', backref='order', cascade='all, delete-orphan')
    shipments = db.relationship('Shipment', backref='order', cascade='all, delete-orphan')


class OrderItem(db.Model):
    __tablename__ = 'order_items'
    id = db.Column(db.Integer, primary_key=True)
    order_id = db.Column(db.Integer, db.ForeignKey('orders.id'))
    title = db.Column(db.String(255))
    sku = db.Column(db.String(64))
    qty = db.Column(db.Integer)
    unit_price = db.Column(db.Integer)  # 分


class Shipment(db.Model):
    __tablename__ = 'shipments'
    id = db.Column(db.Integer, primary_key=True)
    order_id = db.Column(db.Integer, db.ForeignKey('orders.id'))
    carrier = db.Column(db.String(64))          # 物流承运商
    tracking_no = db.Column(db.String(64))      # 物流单号
    shipped_at = db.Column(db.DateTime)


class PaymentIntent(db.Model):
    __tablename__ = 'payment_intents'
    """形态B使用：先收款后建单的占位记录/对账用"""
    id = db.Column(db.Integer, primary_key=True)
    biz_ref = db.Column(db.String(64), index=True)  # 你的业务引用，比如预下单号/购物车号/用户ID等
    amount = db.Column(db.Integer)
    currency = db.Column(db.String(8), default="USD")
    paypal_order_id = db.Column(db.String(64))
    paypal_capture_id = db.Column(db.String(64))
    status = db.Column(db.String(20), default="created")  # created/captured/failed
    created_at = db.Column(db.DateTime, default=datetime.utcnow)


class AdminUser(UserMixin, db.Model):
    __tablename__ = 'admin_users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password_hash = db.Column(db.String(255), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    def get_id(self):
        return f"admin:{self.id}"


class CustomerUser(db.Model, UserMixin):
    __tablename__ = 'customer_users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(32), unique=True, nullable=False, index=True)
    email = db.Column(db.String(255), unique=True, nullable=False, index=True)
    password_hash = db.Column(db.String(255), nullable=False)
    shipping_address = db.Column(db.Text, nullable=True)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

    recipient_name = db.Column(db.String(64), nullable=True)  # 收件人姓名
    phone = db.Column(db.String(32), nullable=True)  # 联系电话（国际）
    postal_code = db.Column(db.String(20), nullable=True)  # 邮编

    # 让 Flask-Login 能区分不同类型的用户（避免与 AdminUser id 冲突）
    def get_id(self):
        return f"cust:{self.id}"




class CategorySlugAlias(db.Model):
    __tablename__ = 'category_slug_alias'
    id = db.Column(db.Integer, primary_key=True)
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'), nullable=False)
    old_slug = db.Column(db.String(120), nullable=False, unique=True)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)


class Category(db.Model):
    __tablename__ = 'categories'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False, unique=True)
    slug = db.Column(db.String(100), nullable=False, unique=True)
    sort_order = db.Column(db.Integer, default=0)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    products = db.relationship('Product', backref='category', lazy=True)
    i18n = db.relationship('CategoryI18n', backref='category', lazy=True, cascade='all, delete-orphan')

    def set_slug(self):
        self.slug = canonical_slug(self.name)


class CategoryI18n(db.Model):
    __tablename__ = 'category_i18n'
    id = db.Column(db.Integer, primary_key=True)
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'), nullable=False)
    lang = db.Column(db.String(8), nullable=False) # 'en', 'zh'...
    name = db.Column(db.String(80), nullable=False)
    __table_args__ = (db.UniqueConstraint('category_id', 'lang', name='uq_category_lang'),)


class Product(db.Model):
    __tablename__ = 'products'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(150), nullable=False)
    subtitle = db.Column(db.String(255))
    description = db.Column(db.Text)
    price = db.Column(db.Integer)  # 分为单位；或用 Decimal
    currency = db.Column(db.String(8), default='USD')
    sku = db.Column(db.String(64), unique=True)
    material = db.Column(db.String(64))  # 如：和田玉、翡翠
    has_certificate = db.Column(db.Boolean, default=True)
    can_direct_pay = db.Column(db.Boolean, default=True)
    size_value = db.Column(db.Float)  # 例如 58.0
    size_length = db.Column(db.Float)  # 长度
    size_width = db.Column(db.Float)  # 宽度
    size_height = db.Column(db.Float)  # 高度
    size_unit = db.Column(db.String(8), default='mm')
    weight_value = db.Column(db.Float)  # 例如 52.5
    weight_unit = db.Column(db.String(8), default='g')
    stock = db.Column(db.Integer, default=1)  # 默认库存 1
    # ★ 新增：起订量（默认 1）
    min_order_qty = db.Column(db.Integer, default=1, nullable=False)
    is_published = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    cover_image = db.Column(db.String(255))
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'), nullable=False)

    images = db.relationship('ProductImage', backref='product', lazy=True, cascade='all, delete-orphan')
    i18n = db.relationship('ProductI18n', backref='product', lazy=True, cascade='all, delete-orphan')

    # 简单的取翻译工具：没有则回退到默认中文字段
    def t(self, field: str, lang: str | None):
        if not lang or lang == 'zh':
            return getattr(self, field, None)

    # 找 i18n
        for row in self.i18n:
            if row.lang == lang:
                return getattr(row, field, None) or getattr(self, field, None)
        return getattr(self, field, None)


class ProductI18n(db.Model):
    __tablename__ = 'product_i18n'
    id = db.Column(db.Integer, primary_key=True)
    product_id = db.Column(db.Integer, db.ForeignKey('products.id'), nullable=False)
    lang = db.Column(db.String(8), nullable=False) # 'en', 'zh'...
    # 可翻译字段
    title = db.Column(db.String(150))
    subtitle = db.Column(db.String(255))
    description = db.Column(db.Text)
    material = db.Column(db.String(64))
    __table_args__ = (db.UniqueConstraint('product_id', 'lang', name='uq_product_lang'),)


class ProductImage(db.Model):
    __tablename__ = 'product_images'
    id = db.Column(db.Integer, primary_key=True)
    product_id = db.Column(db.Integer, db.ForeignKey('products.id'), nullable=False)
    image_path = db.Column(db.String(255), nullable=False)
    sort_order = db.Column(db.Integer, default=0)




class Banner(db.Model):
    __tablename__ = 'banners'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(150))
    image_path = db.Column(db.String(255), nullable=False)
    link_url = db.Column(db.String(255))
    sort_order = db.Column(db.Integer, default=0)
    is_active = db.Column(db.Boolean, default=True)